// Copyright 2012 Google Inc. All Rights Reserved.

package com.google.appengine.preferencessync.internal.network;

import com.google.appengine.preferencessync.adapter.AbstractSyncablePrefsService.RequestProcessor;
import com.google.appengine.preferencessync.internal.Config;
import com.google.appengine.preferencessync.internal.InternalSyncException;
import com.google.appengine.preferencessync.internal.RequestPaging;
import com.google.appengine.syncserver.shared.HttpParameterDefinitions.ClientRequest;
import com.google.appengine.syncserver.shared.PropertyChange;
import com.google.appengine.syncserver.shared.WriteUpdatesPageRequest;
import com.google.appengine.syncserver.shared.WriteUpdatesResponse;

import java.util.ArrayList;

/*
 * Cacher for caching server pages.
 */
public class UpdatesToServerCacher {
  // Store all the pages here.
  private final RequestPaging requestPaging;

  private final String preferences;
  private final long headVersionWhileReading;
  private final Config config;
  private boolean firstPage = true;

  private RequestProcessor requestProcessor;

  /**
   * Constructor
   *
   * @param config
   * @param changes
   * @param preferences
   * @param headVersionWhileReading
   * @param requestProcessor
   */
  public UpdatesToServerCacher(
      Config config, ArrayList<PropertyChange> changes, String preferences,
      long headVersionWhileReading, RequestProcessor requestProcessor) {
    requestPaging = new RequestPaging(changes, config.getPagingSize());
    this.preferences = preferences;
    this.headVersionWhileReading = headVersionWhileReading;
    this.config = config;
    this.requestProcessor = requestProcessor;
  }

  /**
   * Resume sending the pages.
   *
   * @return the max server head version.
   * @throws InternalSyncException
   */
  public long resumeSendingPages() throws InternalSyncException {
    WriteUpdatesResponse response = null;
    // Page until all pages have been sent.
    while(requestPaging.hasNextChangeList()) {
      ArrayList<PropertyChange> changes = requestPaging.getNextChangeList();
      boolean lastPage = !requestPaging.hasNextChangeList();
      WriteUpdatesPageRequest request = new WriteUpdatesPageRequest(config.getUsername(),
          config.getClientId(), preferences, firstPage, lastPage, headVersionWhileReading,
          config.getGCMRegistrationId(), changes.toArray(new PropertyChange[changes.size()]));
      String responseString = HttpUtils.sendRequest(requestProcessor, config.getRootUrl(),
          ClientRequest.WRITE_REQUEST, request.toString());
      response = WriteUpdatesResponse.valueOf(responseString);
      firstPage = false;
    }

    if (response != null) {
      return response.getMaxVersion();
    }
    return headVersionWhileReading;
  }

  /**
   * @return preferenceName for which this class is caching.
   */
  public String getPreferencesName() {
    return preferences;
  }
}
